/* $RCSFile: ADNDynCommonDoc.cs $
 * Apache license v2 2011 by Christian Surieux
 * $Source: ?/CRMWrapper3/DynEntities/ADNDynCommonDoc.cs $
 * $log$
 * Revision 6 2010/08/06 19:56:32  christian.surieux
 *   Added Log to All cs files
 */

/* Copyrights Christian Surieux 2010 */
/* Class ADNDynCommonDoc */
/* Date 2010-01-10 19:34:29Z */

using System;
using System.Diagnostics;
using System.Collections;
using System.ComponentModel;
using System.Collections.Generic;
using System.Text;
using System.Globalization;
using System.IO;
using System.Web.Services.Protocols;
using System.Data;

using CrmSdk;

namespace AddonNice.CRMWrapper
{
    /// <summary>
    /// Abstract class to use as base for all attachement related entities: SalesLiteratureItem,ActivityAttachement, Annotation
    /// </summary>
    public abstract class ADNDynCommonDoc : DynEntity
    {

        public ADNDynCommonDoc() : base() { }
        public ADNDynCommonDoc(CRMWrapperBase w,string entName): base(w,entName) {}
        public ADNDynCommonDoc(CRMWrapperBase w,string entName,Guid CrmId) : base(w,entName,CrmId) {}
        public ADNDynCommonDoc(CRMWrapperBase w,string entName,InternalDynamicEntity e) : base(w,entName,e,null,null) { }
        public ADNDynCommonDoc(CRMWrapperBase w,string entName,InternalDynamicEntity e,PropertyDescriptorCollection prop,InternalColumnSet s) : base(w,entName,e,prop,s) {}
        public ADNDynCommonDoc(ResetWrapperHandler fn,string entName) : base(fn,entName) {}
        public ADNDynCommonDoc(ResetWrapperHandler fn,string entName,Guid CrmId) : base(fn,entName,CrmId) { }
        public ADNDynCommonDoc(ResetWrapperHandler fn,string entName,InternalDynamicEntity e) : base(fn,entName,e,null,null) { }
        public ADNDynCommonDoc(ResetWrapperHandler fn,string entName,InternalDynamicEntity e,PropertyDescriptorCollection prop,InternalColumnSet s) : base(fn,entName,e,prop,s) { }

        /* Properties */

        [CrmDynAttribute(CrmStr.salesliteratureitem),CrmDynAttribute(CrmStr.annotation),CrmDynAttribute(CrmStr.activitymimeattachment)]
        public string filename
        {
            get { return StringPropertyValue(CrmStr.filename); }
            set { AddStringProperty(CrmStr.filename,value); }
        }

        [CrmDynAttribute(CrmStr.salesliteratureitem),CrmDynAttribute(CrmStr.annotation),CrmDynAttribute(CrmStr.activitymimeattachment)]
        public int filesize
        {
            get { return NumberPropertyValue(CrmStr.filesize); }
            set { AddNumberProperty(CrmStr.filesize,value); }
        }

        [CrmDynAttribute(CrmStr.salesliteratureitem),CrmDynAttribute(CrmStr.annotation),CrmDynAttribute(CrmStr.activitymimeattachment)]
        public string mimetype
        {
            get { return StringPropertyValue(CrmStr.mimetype); }
            set { AddStringProperty(CrmStr.mimetype,value); }
        }

        #region Utilities
        
        public byte[] DownLoadFile(string url,ref bool OkDownload)
        {
            bool Ok     =   OkDownload;
            byte[] buf  =   wrapper.DownLoadFile(url,ref Ok); 
            OkDownload  =   Ok;
            return buf;
        }
        
        string _DocumentsFolder =   string.Empty;
        public string DocumentsFolder
        {
            get
            {
                return _DocumentsFolder;
            }
            set
            {
                _DocumentsFolder    =   value;
            }
        }
        public string LoadFile(string wDocumentsFolder, string fileName,ref bool wOkLoad)
        {
            DocumentsFolder         =   wDocumentsFolder;
            bool OkLoad             =   wOkLoad;
            string ret              =   LoadFile(fileName,ref OkLoad);
            wOkLoad                 =   OkLoad;
            return ret;
        }

        public string LoadFile(string fileName,ref bool OkLoad)
        {
            string encodedData              =   string.Empty;
            string path                     =   System.IO.Path.Combine(DocumentsFolder,fileName);
            if (CRMDynTraceSwitch.Sw.TraceVerbose)
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]ADNDynCommonDoc LoadFile filename '{0}', path: {1}.", fileName, path), CRMDynTraceSwitch.Sw.Info);
            FileInfo pointer                =   null;
            FileStream fileStream           =   null;
            OkLoad                          =   false;
            try
            {
                if (File.Exists(path))
                {
                    pointer                 =   new FileInfo(path);
                    fileStream              =   pointer.OpenRead();
                    if (fileStream.Length > 0)
                    {
                        byte[] byteData     =   new byte[(int)fileStream.Length];
                        fileStream.Read(byteData, 0, (int)fileStream.Length);
                        fileStream.Flush();
                        encodedData         =   System.Convert.ToBase64String(byteData);
                        OkLoad              =   true;
                    }
                }
            }
            catch (Exception ex)
            {
                if (CRMDynTraceSwitch.Sw.TraceError)
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]ADNDynCommonDoc LoadFile filename '{0}', ex: {1}.", fileName, ex), CRMDynTraceSwitch.Sw.Info);
            }
            finally
            {
                if (fileStream != null)
                {
                    fileStream.Close();
                }
            }
            return encodedData;
        }

        /// <summary>
        /// Refresh a file in an attachment
        /// Works only with filename written in entity
        /// Corresponding file must be present in the document folder
        /// file is read, then crm is updated 
        /// </summary>
        public bool ResetAttachment()
        {
            string data64                       =   string.Empty;
            bool isOk                           =   false;
            try
            {
                bool OkLoad                     =   false;
                data64                          =   LoadFile(filename,ref OkLoad);
                if (CRMDynTraceSwitch.Sw.TraceVerbose || CRMDynTraceSwitch.Sw.TraceVerbose)
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]ADNDynCommonDoc ResetAttachment salesliteratureitem download Ok: {0}, File: {1}.",
                        OkLoad,filename), (CRMDynTraceSwitch.Sw.TraceVerbose) ? CRMDynTraceSwitch.Sw.Info:CRMDynTraceSwitch.Sw.Info);
                if (OkLoad)
                {
                    if (CRMDynTraceSwitch.Sw.TraceVerbose)
                        Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]ADNDynCommonDoc ResetAttachment annotation data.Length: {0}.", data64.Length), CRMDynTraceSwitch.Sw.Info);
                    switch(SchemaName)
                    {
                        case CrmStr.activitymimeattachment:
                            AddStringProperty(CrmStr.body, data64);
                        break;
                        case CrmStr.annotation:
                        case CrmStr.salesliteratureitem:
                            AddStringProperty(CrmStr.documentbody, data64);
                        break;
                    }
                    Update();
                    isOk                        =   true;
                    if (CRMDynTraceSwitch.Sw.TraceVerbose)
                        Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]ADNDynCommonDoc ResetAttachment END Ok: {0}.",isOk), CRMDynTraceSwitch.Sw.Info);
                }
            }
            catch (SoapException sx)
            {
                if (CRMDynTraceSwitch.Sw.TraceError || CRMDynTraceSwitch.Sw.TraceVerbose)
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]ADNDynCommonDoc ResetAttachment soap ex : {0}-{1}",sx, sx.Detail.InnerText), CRMDynTraceSwitch.Sw.Info);
                throw;
            }
            catch (Exception ex)
            {
                if (CRMDynTraceSwitch.Sw.TraceError || CRMDynTraceSwitch.Sw.TraceVerbose)
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]ADNDynCommonDoc ResetAttachment  ex : {0}",ex),CRMDynTraceSwitch.Sw.Info);
                throw;
            }
            if (CRMDynTraceSwitch.Sw.TraceVerbose || CRMDynTraceSwitch.Sw.TraceVerbose)
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]ADNDynCommonDoc ResetAttachment END isOk: {0}.",isOk),(CRMDynTraceSwitch.Sw.TraceVerbose)? CRMDynTraceSwitch.Sw.Info:CRMDynTraceSwitch.Sw.Info);
            return isOk;
        }
        
           
        public void SaveFile(string PathToSave,string filename,byte[] buffer)
		{
			if (CRMDynTraceSwitch.Sw.TraceVerbose)
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]ADNDynCommonDoc SaveFile BEG PathToSave: {0}, filename: {1}",PathToSave,filename),CRMDynTraceSwitch.Sw.Info);
            string physicalPath		=   System.IO.Path.Combine(PathToSave, filename);
			if (CRMDynTraceSwitch.Sw.TraceVerbose)
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]ADNDynCommonDoc SaveFile physicalPath: {0}",physicalPath),CRMDynTraceSwitch.Sw.Info);
			// Delete file before upload
			while(File.Exists(physicalPath))
			{
				try
				{
					File.Delete(physicalPath);
				}
				catch(Exception ex)
				{
					if (CRMDynTraceSwitch.Sw.TraceError)
                        Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]ADNDynCommonDoc SaveFile Deleting: {0}, ex: {1}",physicalPath,ex),CRMDynTraceSwitch.Sw.Info);
				}
			}
            FileStream fs           =   null;
            BinaryWriter w          =   null;
            try
            {
                // Save file to uploads directory
                fs                  =   new FileStream(physicalPath, FileMode.Create);
                w                   =   new BinaryWriter(fs);
                w.Write(buffer);
                if (CRMDynTraceSwitch.Sw.TraceVerbose)
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]ADNDynCommonDoc SaveFile Ok buffer.Length: {0}.", buffer.Length), CRMDynTraceSwitch.Sw.Info);
            }
            catch (Exception ex)
            {
                if (CRMDynTraceSwitch.Sw.TraceError)
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]ADNDynCommonDoc SaveFile Saving: {0}, ex: {1}", physicalPath, ex), CRMDynTraceSwitch.Sw.Info);
            }
            finally
            {
                if ( w != null )
                    w.Close();
                if ( fs != null )
                    fs.Close();
            }

		}

        public virtual string MakeOpenUrlFmt()
        {
            string url          =   string.Format("{0}/Activities/Attachment/download.aspx?AttachmentType={1}&AttachmentId={{{{{{0}}}}}}",
                                                                    wrapper.DownloadServerUrl, ObjectTypeCode);
            if (CRMDynTraceSwitch.Sw.TraceVerbose)
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]ADNDynCommonDoc MakeOpenUrlFmt salesliteratureitem Url: {0}.", url), CRMDynTraceSwitch.Sw.Info);
            return url;
        }
        
        /// <summary>
        /// Extracts the attached file from CRM and save it in the folder document
        /// Old version Crm3 and Crm4 does a file download from a dedicated crm url
        /// </summary>
        public byte[] DownloadAttachment(bool save,string PathToSave, ref bool isOk)
        {
            byte[] data                 =   null;
            isOk                        =   false;
            try
            {
                string attachid         =   PrimaryKeyGuidValue.ToString();
                if (CRMDynTraceSwitch.Sw.TraceVerbose)
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]ADNDynCommonDoc DownloadAttachment attachid: {0}, filename: {1}, fileSize: {2}.",
                        new object[]{attachid,filename,filesize}),CRMDynTraceSwitch.Sw.Info);
                string url              =   string.Format(MakeOpenUrlFmt(),attachid);
                bool OkDownload         =   false;
                data                    =   DownLoadFile(url,ref OkDownload);
                if (CRMDynTraceSwitch.Sw.TraceVerbose || CRMDynTraceSwitch.Sw.TraceVerbose)
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]ADNDynCommonDoc DownloadAttachment download Ok: {0}, File: {1}.",
                        OkDownload,filename), (CRMDynTraceSwitch.Sw.TraceVerbose) ? CRMDynTraceSwitch.Sw.Info:CRMDynTraceSwitch.Sw.Info);
                if (OkDownload)
                {
                    if (CRMDynTraceSwitch.Sw.TraceVerbose)
                        Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]ADNDynCommonDoc DownloadAttachment data.Length: {0}.", data.Length), CRMDynTraceSwitch.Sw.Info);
                    if ( save)
                        SaveFile(PathToSave,filename,data);
                }
            }
            catch (SoapException sx)
            {
                if (CRMDynTraceSwitch.Sw.TraceError || CRMDynTraceSwitch.Sw.TraceVerbose)
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]ADNDynCommonDoc DownloadAttachment soap ex : {0}-{1}",sx, sx.Detail.InnerText), CRMDynTraceSwitch.Sw.Info);
                throw;
            }
            catch (Exception ex)
            {
                if (CRMDynTraceSwitch.Sw.TraceError || CRMDynTraceSwitch.Sw.TraceVerbose)
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]ADNDynCommonDoc DownloadAttachment  ex : {0}",ex),CRMDynTraceSwitch.Sw.Info);
                throw;
            }
            if (CRMDynTraceSwitch.Sw.TraceVerbose || CRMDynTraceSwitch.Sw.TraceVerbose)
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]ADNDynCommonDoc DownloadAttachment END isOk: {0}.",
                    isOk),(CRMDynTraceSwitch.Sw.TraceVerbose)? CRMDynTraceSwitch.Sw.Info:CRMDynTraceSwitch.Sw.Info);
            return data;
        }

        public string DocumentContent
        {
            get
            {
                switch ( SchemaName )
                {
                    case CrmStr.annotation:
                    return ( (ADNDynAnnotation)this ).documentbody;
                    case CrmStr.activitymimeattachment:
                    return ( (ADNDynActivitymimeattachment)this ).body;
                    case CrmStr.salesliteratureitem:
                    return ( (ADNDynSalesliteratureitem)this ).documentbody;
                    default:
                    return string.Empty;
                }
            }
        }

        /// <summary>
        /// Extracts the attached file from CRM and save it in the folder document or return it
        /// New version from rollup 7, take content directly from readen crm entity without doing a file download from a crm url
        /// </summary>
        public byte[] DownloadAttachment2(bool save,string PathToSave)
        {
            byte[] data                 =   null;
            try
            {
                string attachid         =   PrimaryKeyGuidValue.ToString();
                if (CRMDynTraceSwitch.Sw.TraceVerbose)
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]ADNDynCommonDoc DownloadAttachment2 attachid: {0}, filename: {1}, fileSize: {2}.",
                        new object[]{attachid,filename,filesize}),CRMDynTraceSwitch.Sw.Info);
                data                    =   new UTF8Encoding(true).GetBytes(DocumentContent);
                if (CRMDynTraceSwitch.Sw.TraceVerbose)
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]ADNDynCommonDoc DownloadAttachment2 data.Length: {0}.", data.Length), CRMDynTraceSwitch.Sw.Info);
                if ( save)
                    SaveFile(PathToSave,filename,data);
            }
            catch (Exception ex)
            {
                if (CRMDynTraceSwitch.Sw.TraceError || CRMDynTraceSwitch.Sw.TraceVerbose)
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]ADNDynCommonDoc DownloadAttachment2  ex : {0}",ex),CRMDynTraceSwitch.Sw.Info);
                throw;
            }
            if (CRMDynTraceSwitch.Sw.TraceVerbose || CRMDynTraceSwitch.Sw.TraceVerbose)
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]ADNDynCommonDoc DownloadAttachment2 END size: {0}.",
                    (data ==null)?0:data.Length),(CRMDynTraceSwitch.Sw.TraceVerbose)? CRMDynTraceSwitch.Sw.Info:CRMDynTraceSwitch.Sw.Info);
            return data;
        }
        
        #endregion

    }
}